// VideoGrab.cpp : implementation file
//

#include "stdafx.h"
#include "manualCalib.h"
#include "VideoGrab.h"
#include "cvxCapture.h"
#include "cvvImage.h"
#include "cvxVideo.h"


// CVideoGrab dialog

IMPLEMENT_DYNAMIC(CVideoGrab, CDialog)

CVideoGrab::CVideoGrab(CWnd* pParent /*=NULL*/)
	: CDialog(CVideoGrab::IDD, pParent)
	, m_leftVideo(NULL)
	, m_rightVideo(NULL)
	, m_playMode(false)
	, m_grabList(NULL)
{

}

CVideoGrab::~CVideoGrab()
{
	if (m_leftVideo)
	{
		delete m_leftVideo, m_leftVideo = NULL;
	}
	if (m_rightVideo)
	{
		delete m_rightVideo, m_rightVideo = NULL;
	}
}

/************************************************************************/
/* added                                                                */
/************************************************************************/
bool CVideoGrab::SetVideo(const string &leftVideoFile, const string &rightVideoFile)
{
	//capture video from filess
	CvCapture *leftCap = cvCaptureFromFile(leftVideoFile.c_str());
	if (!leftCap)
	{
		return false;
	}
	CvCapture *rightCap = cvCaptureFromFile(rightVideoFile.c_str());
	if (!rightCap)
	{
		return false;
	}
	m_leftFileName = leftVideoFile;
	m_rightFileName = rightVideoFile;
	m_leftVideo = new CvxArbitraryCapture(leftCap);
	m_rightVideo = new CvxArbitraryCapture(rightCap);
	ASSERT(m_leftVideo);
	ASSERT(m_rightVideo);

	m_currentFrame = 0;

	return true;

}

void CVideoGrab::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_VIDEO_GRAM_SLIDER, m_videoSlider);
	DDX_Control(pDX, IDC_VIDEO_GRAB_LEFT_PIC, m_leftFrame);
	DDX_Control(pDX, IDC_VIDEO_GRAB_RIGHT_PIC, m_rightFrame);
}


BEGIN_MESSAGE_MAP(CVideoGrab, CDialog)
	ON_WM_PAINT()
	ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_VIDEO_GRAM_SLIDER, &CVideoGrab::OnNMReleasedcaptureVideoGramSlider)
	ON_BN_CLICKED(IDC_VIDEO_GRAB_FIRST_FRAME, &CVideoGrab::OnBnClickedVideoGrabFirstFrame)
	ON_BN_CLICKED(IDC_VIDEO_GRAB_BACKWARD, &CVideoGrab::OnBnClickedVideoGrabBackward)
	ON_BN_CLICKED(IDC_VIDEO_GRAB_FORWARD, &CVideoGrab::OnBnClickedVideoGrabForward)
	ON_BN_CLICKED(IDC_VIDEO_GRAB_END_FRAME, &CVideoGrab::OnBnClickedVideoGrabEndFrame)
	ON_BN_CLICKED(IDC_VIDEO_GRAB_PLAY_STOP, &CVideoGrab::OnBnClickedVideoGrabPlayStop)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_VIDEO_GRAB_GRAB, &CVideoGrab::OnBnClickedVideoGrabGrab)
	ON_BN_CLICKED(IDC_VIDEO_GRAB_GRABLIST, &CVideoGrab::OnBnClickedVideoGrabGrablist)
	ON_BN_CLICKED(IDC_BUTTON_START_FRAME, &CVideoGrab::OnBnClickedButtonStartFrame)
	ON_BN_CLICKED(IDC_BUTTON_END_FRAME, &CVideoGrab::OnBnClickedButtonEndFrame)
	ON_BN_CLICKED(IDC_BUTTON_SAVE_VIDEO, &CVideoGrab::OnBnClickedButtonSaveVideo)
END_MESSAGE_MAP()


// CVideoGrab message handlers

BOOL CVideoGrab::OnInitDialog()
{
	CDialog::OnInitDialog();

	// TODO:  Add extra initialization here

	//set slider
	if (m_leftVideo)
	{
		m_videoSlider.SetRange(0, (int)(m_leftVideo->maxFrame()));
	}
	m_videoSlider.SetPos(0);



	//moive left right frame window in OnPaint
	//
	m_leftFrame.MoveWindow(10, 10, 480, 270);
	m_rightFrame.MoveWindow(510, 10, 480, 270);

	//set a timer
	SetTimer(1, 1000/24, 0);

	m_startFrame = 0;
	m_endFrame = 0;

	return TRUE;  // return TRUE unless you set the focus to a control
	// EXCEPTION: OCX Property Pages should return FALSE
}



void CVideoGrab::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	// TODO: Add your message handler code here
	// Do not call CDialog::OnPaint() for painting messages

	//draw left and right frame
	IplImage *leftFrame  = m_leftVideo->GetFrame(m_currentFrame);
	IplImage *rightFrame = m_rightVideo->GetFrame(m_currentFrame);


	if (leftFrame)
	{
		CmfcImage leftImageDrawer;		
		CDC *pDc = m_leftFrame.GetDC();	
		CRect rect;
		ASSERT(pDc);
		HDC hDc = pDc->GetSafeHdc();
		m_leftFrame.GetClientRect(&rect);
		leftImageDrawer.passImage(leftFrame);
		leftImageDrawer.DrawToHDC(hDc, &rect);
		ReleaseDC(pDc);
	}
	if (rightFrame)
	{
		CmfcImage rightImageDrawer;
		rightImageDrawer.passImage(rightFrame);
		CDC *pDc = m_rightFrame.GetDC();	
		CRect rect;
		ASSERT(pDc);

		HDC hDc = pDc->GetSafeHdc();
		m_rightFrame.GetClientRect(&rect);
		rightImageDrawer.DrawToHDC(hDc, &rect);
		ReleaseDC(pDc);
	}	
}

void CVideoGrab::OnNMReleasedcaptureVideoGramSlider(NMHDR *pNMHDR, LRESULT *pResult)
{
	// TODO: Add your control notification handler code here
	*pResult = 0;
	m_currentFrame = m_videoSlider.GetPos();
	InvalidateRect(0, FALSE);
}

void CVideoGrab::OnBnClickedVideoGrabFirstFrame()
{
	// TODO: Add your control notification handler code here
	m_currentFrame = 0;
	m_playMode = false;
	m_videoSlider.SetPos(m_currentFrame);
	InvalidateRect(0, FALSE);
}

void CVideoGrab::OnBnClickedVideoGrabBackward()
{
	// TODO: Add your control notification handler code here
	if (m_currentFrame > 0)
	{
		m_currentFrame--;
	}
	m_playMode = false;
	m_videoSlider.SetPos(m_currentFrame);
	InvalidateRect(0, FALSE);
}

void CVideoGrab::OnBnClickedVideoGrabForward()
{
	// TODO: Add your control notification handler code here
	if (m_currentFrame < m_leftVideo->maxFrame())
	{
		m_currentFrame++;
	}
	m_playMode = false;
	m_videoSlider.SetPos(m_currentFrame);
	InvalidateRect(0, FALSE);
}

void CVideoGrab::OnBnClickedVideoGrabEndFrame()
{
	// TODO: Add your control notification handler code here
	m_currentFrame = m_leftVideo->maxFrame();
	m_playMode = false;
	m_videoSlider.SetPos(m_currentFrame);
	InvalidateRect(0, FALSE);
}

void CVideoGrab::OnBnClickedVideoGrabPlayStop()
{
	// TODO: Add your control notification handler code here
	m_playMode = !m_playMode;
}

void CVideoGrab::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: Add your message handler code here and/or call default
	if (m_playMode)
	{
		m_currentFrame = m_videoSlider.GetPos();
		if (m_currentFrame < m_leftVideo->maxFrame())
		{
			m_currentFrame++;
		}
		InvalidateRect(0, FALSE);
		m_videoSlider.SetPos(m_currentFrame);
	}	
	CDialog::OnTimer(nIDEvent);
}

void CVideoGrab::OnBnClickedVideoGrabGrab()
{
	// TODO: Add your control notification handler code here

	// grab image pair from image, store in CGrabList
	int curFrameNum = m_currentFrame;
	IplImage *leftFrame = m_leftVideo->GetFrame(curFrameNum);
	IplImage *rightFrame = m_rightVideo->GetFrame(curFrameNum);
	if (leftFrame && rightFrame)
	{
		if (!m_grabList)
		{
			m_grabList = new CGrabList(this);
			m_grabList->Create(CGrabList::IDD, this);
		}
		m_grabList->AddList(curFrameNum, leftFrame, rightFrame);
	}
	else
	{
		AfxMessageBox(_T("Grab Failed!"), MB_OK);
		return;
	}
	
}

void CVideoGrab::OnBnClickedVideoGrabGrablist()
{
	// TODO: Add your control notification handler code here

	//show grab list content
	if (m_grabList)
	{
		m_grabList->ShowWindow(SW_SHOW);
		m_grabList->SetForegroundWindow();
	}
	else
	{
		m_grabList = new CGrabList(this);
		m_grabList->Create(CGrabList::IDD, this);
		m_grabList->ShowWindow(SW_SHOW);
	}

}

void CVideoGrab::OnBnClickedButtonStartFrame()
{
	// TODO: Add your control notification handler code here
	m_startFrame = m_currentFrame;
}

void CVideoGrab::OnBnClickedButtonEndFrame()
{
	// TODO: Add your control notification handler code here
	m_endFrame = m_currentFrame;
}

void CVideoGrab::OnBnClickedButtonSaveVideo()
{
	// TODO: Add your control notification handler code here
	if (m_endFrame > m_startFrame + 24)
	{
		//left
		{
			string saveLeftFile;
			CFileDialog dlgLeftFileL(FALSE, "avi", "left.avi", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "AVI (*.avi)", NULL);
			if (dlgLeftFileL.DoModal() == IDOK)
			{
				saveLeftFile = dlgLeftFileL.GetPathName();		
			}
			if (!saveLeftFile.empty())
			{
				IplImage *leftFrame = m_leftVideo->GetFrame(m_currentFrame);
				bool isOk = CvxVideo::writeToAVI(m_leftFileName, saveLeftFile, 
					24, cvSize(leftFrame->width, leftFrame->height), m_startFrame, m_endFrame - m_startFrame, 2);
				if (isOk)
				{
					AfxMessageBox(_T("left video cut complete"), MB_OK);
				}			
			}
		}

		//right
		{
			string saveRightFile;
			CFileDialog dlgRightFileL(FALSE, "avi", "right.avi", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "AVI (*.avi)", NULL);
			if (dlgRightFileL.DoModal() == IDOK)
			{
				saveRightFile = dlgRightFileL.GetPathName();		
			}
			if (!saveRightFile.empty())
			{
				IplImage *rightFrame = m_leftVideo->GetFrame(m_currentFrame);
				bool isOk = CvxVideo::writeToAVI(m_rightFileName, saveRightFile, 
					24, cvSize(rightFrame->width, rightFrame->height), m_startFrame, m_endFrame - m_startFrame, 2);
				if (isOk)
				{
					AfxMessageBox(_T("right video cut complete"), MB_OK);
				}			
			}
		}
	}
	else
	{
		AfxMessageBox(_T("Frame number is less than 24!"), MB_OK);
	}
}
